#include "Vectors.h"

using namespace me;
using namespace std;

//Vector2i
Vector2i::Vector2i(int nx, int ny): x(nx), y(ny)
{

}


Vector2i::~Vector2i()
{

}

Vector2i& Vector2i::operator+=(me::Vector2i const& b)
{
    this->x += b.x;
    this->y += b.y;
    return *this;
}

Vector2i& Vector2i::operator-=(me::Vector2i const& b)
{
    this->x -= b.x;
    this->y -= b.y;
    return *this;
}


Vector2i& Vector2i::operator*=(int const& b)
{
    this->x *= b;
    this->y *= b;
    return *this;
}

double Vector2i::getLength()
{
    double ret = sqrt(pow(x, 2) + pow(y, 2));
    return ret;
}

float Vector2i::getOrientation()
{
    float ret = atan2(y, x) * 180.0f / PI;
    if (ret < 0.0f)
        ret = 360.0f - ret*-1;
    return ret;
}

Vector2i operator+(me::Vector2i const& a, me::Vector2i const& b)
{
    me::Vector2i aCopy = a;
    aCopy += b;
    return aCopy;
}

Vector2i operator-(me::Vector2i const& a, me::Vector2i const& b)
{
    me::Vector2i aCopy = a;
    aCopy -= b;
    return aCopy;
}

int operator*(me::Vector2i const& a, me::Vector2i const& b)
{
    int ret(0);
    ret += a.x*b.x + a.y*b.y;
    return ret;
}


//Vector2f
Vector2f::Vector2f(float nx, float ny): x(nx), y(ny)
{

}


Vector2f::~Vector2f()
{

}

Vector2f& Vector2f::operator+=(me::Vector2f const& b)
{
    this->x += b.x;
    this->y += b.y;
    return *this;
}

Vector2f& Vector2f::operator-=(me::Vector2f const& b)
{
    this->x -= b.x;
    this->y -= b.y;
    return *this;
}


Vector2f& Vector2f::operator*=(float const& b)
{
    this->x *= b;
    this->y *= b;
    return *this;
}

double Vector2f::getLength()
{
    double ret = sqrt(pow(x, 2) + pow(y, 2));
    return ret;
}

float Vector2f::getOrientation()
{
    float ret = atan2(y, x) * 180.0f / PI;
    if (ret < 0.0f)
        ret = 360.0f - ret*-1;
    return ret;
}

Vector2f operator+(me::Vector2f const& a, me::Vector2f const& b)
{
    me::Vector2f aCopy = a;
    aCopy += b;
    return aCopy;
}

Vector2f operator-(me::Vector2f const& a, me::Vector2f const& b)
{
    me::Vector2f aCopy = a;
    aCopy -= b;
    return aCopy;
}

float operator*(me::Vector2f const& a, me::Vector2f const& b)
{
    float ret(0);
    ret += a.x*b.x + a.y*b.y;
    return ret;
}

//Vector2u
Vector2u::Vector2u(unsigned int nx, unsigned int ny): x(nx), y(ny)
{

}


Vector2u::~Vector2u()
{

}

Vector2u& Vector2u::operator+=(me::Vector2u const& b)
{
    this->x += b.x;
    this->y += b.y;
    return *this;
}

Vector2u& Vector2u::operator-=(me::Vector2u const& b)
{
    this->x -= b.x;
    this->y -= b.y;
    return *this;
}


Vector2u& Vector2u::operator*=(unsigned int const& b)
{
    this->x *= b;
    this->y *= b;
    return *this;
}

double Vector2u::getLength()
{
    double ret = sqrt(pow(x, 2) + pow(y, 2));
    return ret;
}

float Vector2u::getOrientation()
{
    float ret = atan2(y, x) * 180.0f / PI;
    if (ret < 0.0f)
        ret = 360.0f - ret*-1;
    return ret;
}

Vector2u operator+(me::Vector2u const& a, me::Vector2u const& b)
{
    me::Vector2u aCopy = a;
    aCopy += b;
    return aCopy;
}

Vector2u operator-(me::Vector2u const& a, me::Vector2u const& b)
{
    me::Vector2u aCopy = a;
    aCopy -= b;
    return aCopy;
}

unsigned int operator*(me::Vector2u const& a, me::Vector2u const& b)
{
    unsigned int ret(0);
    ret += a.x*b.x + a.y*b.y;
    return ret;
}

ostream& operator<<(ostream& flux, me::Vector2f const& a)
{
    return flux << "(" << a.x << ", " << a.y << ")";
}

ostream& operator<<(ostream& flux, me::Vector2i const& a)
{
    return flux << "(" << a.x << ", " << a.y << ")";
}

ostream& operator<<(ostream& flux, me::Vector2u const& a)
{
    return flux << "(" << a.x << ", " << a.y << ")";
}
